package net.esj.basic.plugins.spring.factory.xml.parser;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import net.esj.basic.dao.DaoProxy;
import net.esj.basic.dao.hibernate.HibernateSourceLocale;
import net.esj.basic.dao.hibernate.impl.HibernateDaoImpl;
import net.esj.basic.dao.jdbc.JdbcSourceLocale;
import net.esj.basic.dao.jdbc.impl.JdbcDaoImpl;

import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

@Deprecated
public class DaoProxyBeanDefinitionParser extends
		AbstractSingleBeanDefinitionParser {

	public static String DEFAULT_DAO_PROXY_BEAN_NAME = DaoProxy.class.getName();
	
	public static Class DEFAULT_PERSISTENT_CLASS = HibernateDaoImpl.class;
	
	public static Map<Class,Class> DEFAULT_DAO_SOURCE;
	static{
		DEFAULT_DAO_SOURCE = new HashMap<Class,Class>();
		DEFAULT_DAO_SOURCE.put( JdbcDaoImpl.class,JdbcSourceLocale.class);
		DEFAULT_DAO_SOURCE.put( HibernateDaoImpl.class,HibernateSourceLocale.class);
	}
	
	@Override
	protected void doParse(Element element, ParserContext parserContext,
			BeanDefinitionBuilder builder) {
		NodeList childNodes = element.getChildNodes();
		String persistentClass =DEFAULT_PERSISTENT_CLASS.getName();
		Properties daoSources = new Properties();
		if(element.hasChildNodes()){
			for (int i = 0; i < childNodes.getLength(); i++) {//註冊所有的子类BEAN
				Node child = childNodes.item(i);
				Element taskElement = (Element) child;
				if("persistentClass".equals(taskElement.getTagName())){
					String className = taskElement.getAttribute("value");
					if(!StringUtils.hasText(className)){
						className = DEFAULT_PERSISTENT_CLASS.getName();
					}
					persistentClass = className;
					Class cls;
					try {
						cls = Class.forName(className);
						String sourceLocale = DEFAULT_DAO_SOURCE.get(cls).getName();
						registerDao(parserContext, className, className, sourceLocale);
					} catch (ClassNotFoundException e) {
						e.printStackTrace();
					}
				}
				else if("daoSources".equals(taskElement.getTagName())){
					if(taskElement.hasChildNodes()){
						NodeList sourcesNodes = taskElement.getChildNodes();
						for (int j = 0; j < childNodes.getLength();j++) {
							Node sourceChild = sourcesNodes.item(j);
							Element sourceElement = (Element) sourceChild;
							String clazz = sourceElement.getAttribute("class");
							String source = sourceElement.getAttribute("source");
							registerDao(parserContext, clazz, clazz, source);
							daoSources.setProperty(clazz,"");
						}
					}else{
						for(Map.Entry<Class, Class> entry: DEFAULT_DAO_SOURCE.entrySet()){
							registerDao(parserContext, entry.getKey().getName(), entry.getKey().getName(), entry.getValue().getName());
						}
					}
				}
			}
		}else{
			registerDao(parserContext, DEFAULT_PERSISTENT_CLASS.getName(), DEFAULT_PERSISTENT_CLASS.getName(), DEFAULT_DAO_SOURCE.get(DEFAULT_PERSISTENT_CLASS).getName());
			
			for(Map.Entry<Class, Class> entry: DEFAULT_DAO_SOURCE.entrySet()){
				registerDao(parserContext, entry.getKey().getName(), entry.getKey().getName(), entry.getValue().getName());
				daoSources.setProperty(entry.getKey().getName(),"");
			}
			
		}
		builder.addPropertyReference("persistentClass", persistentClass);
		builder.addPropertyValue("daoSources", daoSources);
		parserContext.registerBeanComponent(
				new BeanComponentDefinition(builder.getBeanDefinition(),DEFAULT_DAO_PROXY_BEAN_NAME));
	}

	@Override
	protected Class<?> getBeanClass(Element element) {
		return DaoProxy.class;
	}

	protected static void registerDao(
			ParserContext parserContext,  String beanName,String className,String sourcelocale) {
		if (!parserContext.getRegistry().containsBeanDefinition(beanName)) {
			BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(className);
			builder.addPropertyReference("sourceLocale", sourcelocale);
			parserContext.registerBeanComponent(
					new BeanComponentDefinition(builder.getBeanDefinition(),
							beanName));
		}
	}
	

	@Override
	protected String resolveId(Element element,
			AbstractBeanDefinition definition, ParserContext parserContext)
			throws BeanDefinitionStoreException {
		String id = super.resolveId(element, definition, parserContext);
		if(StringUtils.hasText(id)){
			return id;
		}
		return DEFAULT_DAO_PROXY_BEAN_NAME;
	}
	
}
